<template>
  <div class="ma-content-block lg:flex justify-between">
    <div class="lg:w-2/12 w-full p-4 border-r border-gray-100">
      <tree-slider
        :data="fileTypes"
        v-model="defaultFileTypeKey"
        search-placeholder="搜索"
        icon="icon-folder"
        :field-names="{ children: 'children', title: 'name', key: 'value' }"
        @click="onTreeClick"
      />
    </div>
    <div class="lg:w-10/12 w-full p-4 mt-5 lg:mt-0">
      <a-spin :loading="spinLoading" :tip="spinTip" dot style="width: 100%;">
        <a-layout-content class="flex flex-col lg:h-full relative w-full">
          <div ref="searchRef">
            <a-row v-if="showSearch" class="table-search mb-3">
              <a-col :flex="1">
                <a-form
                  class="query-form"
                  :model="query"
                  label-align="left"
                >
                  <a-row :gutter="8">
                    <a-col flex="360px">
                      <a-range-picker v-model="query.range_date" allow-clear/>
                    </a-col>
                    <a-col flex="86px">
                      <a-space :size="6">
                        <a-button type="primary" @click="search()">搜索</a-button>
                        <a-button @click="refresh()">重置</a-button>
                      </a-space>
                    </a-col>
                    <a-col flex="160px" class="group-rifgt">
                      <file-upload :show-file-list="false" accept="*" :is-button="true" button-text="上传" @uploadCallback="uploadCallback"/>
                    </a-col>
                  </a-row>
                </a-form>
              </a-col>
            </a-row>
          </div>
          <div class="table-content">
            <div class="table-header lg:flex justify-between mb-2">
              <a-space class="lg:flex block lg:inline-block">
                <div v-if="tableMode === 'window'" class="custom-checkbox-card">
                  <a-checkbox v-model="checkAll" :indeterminate="checkedAllInd" @change="customSelectAll">全选</a-checkbox>
                </div>
                <a-button size="small" @click="isActivate(selectionKeys, 1)">启用</a-button>
                <a-button status="warning" size="small" @click="isActivate(selectionKeys, 0)">禁用</a-button>
                <a-button type="primary" status="danger" size="small" @click="batchDel()">
                  <template #icon><icon-delete /></template>批量删除
                </a-button>
              </a-space>
              <a-space class="lg:mt-0 mt-2">
                <a-tooltip :content="tableMode === 'list' ? '切换橱窗模式' : '切换列表模式' ">
                  <a-button shape="circle" @click="switchTableMode">
                    <icon-apps v-if="tableMode === 'list'" />
                    <icon-list v-else />
                  </a-button>
                </a-tooltip>
                <a-tooltip content="刷新表格"><a-button shape="circle" @click="refresh()"><icon-refresh /></a-button></a-tooltip>
                <a-tooltip content="显隐搜索"><a-button shape="circle" @click="toggleSearch()"><icon-search /></a-button></a-tooltip>
                <a-tooltip content="设置"><a-button shape="circle" @click="setTableColumns()"><icon-settings /></a-button></a-tooltip>
              </a-space>
            </div>
            <div ref="tableContainerRef" style="overflow-y: auto;">
              <a-table
                v-if="tableMode === 'list'"
                ref="tableRef"
                row-key="id"
                :loading="loading"
                :pagination="false"
                :data="renderData"
                :bordered="{ wrapper: true, cell: true }"
                :row-selection="rowSelection"
                :scroll="tableScroll"
                column-resizable
                @selection-change="selectionChange"
                @page-change="onPageChange"
                @page-size-change="onPageSizeChange"
              >
                <template #columns>
                  <vue-table-column :columns="columns">
                    <template #file_url="{ record }">
                      <a-image v-if="record.file_type === 'image'" :src="record.full_file_url" width="40" height="40"/>
                      <video v-else-if="record.file_type === 'video'" width="100%" height="100%" controls>
                        <source :src="record.full_file_url" type="video/mp4">
                        <object :data="record.full_file_url" width="100%" height="100%">
                          <embed :src="record.full_file_url" width="100%" height="100%">
                        </object>
                      </video>
                      <audio v-else-if="record.file_type === 'audio'" controls>
                        <source :src="record.full_file_url" type="audio/mp3">
                        <embed :src="record.full_file_url" width="100%" height="100%">
                      </audio>
                      <div v-else-if="record.file_type === 'word'" :src="record.file_url">
                        <icon-drive-file size="50"/>
                      </div>
                      <div v-else :src="record.full_file_url">
                        <icon-folder size="50"/>
                      </div>
                    </template>
                    <template #operations="{ record }">
                      <a-button type="primary" status="danger" size="small" @click="del([record])">删除</a-button>
                    </template>
                  </vue-table-column>
                </template>
              </a-table>
              <a-checkbox-group v-if="tableMode === 'window'" v-model="checkedIds" @change="selectGroup">
                <a-image-preview-group infinite>
                  <a-space class="window-list">
                    <template v-for="record in renderData" :key="record.id">
                      <div class="mb-2 image-content">
                        <a-checkbox :value="record.id" class="checkbox">
                          <template #checkbox="{ checked }">
                            <a-tag :checked="checked" color="blue" checkable><icon-check />选择</a-tag>
                          </template>
                        </a-checkbox>
                        <a-image
                          :src="record.full_file_url"
                          show-loader
                          :title="record.file_name"
                          :description="`大小：${record.file_size}`"
                          width="200"
                          height="200"
                        >
                          <template #extra>
                            <div class="actions">
                              <a-tooltip content="下载此文件">
                                <span class="action" @click="download(record.full_file_url)"><icon-download /></span>
                              </a-tooltip>
                              <a-tooltip>
                                <span class="action"><icon-info-circle /></span>
                                <template #content>
                                  <div>存储目录：{{ record.file_url }}</div>
                                  <div>文件夹：{{ record.folder }}</div>
                                  <div>上传时间：{{ record.created_at }}</div>
                                  <div>存储位置：{{ record.storage }}</div>
                                </template>
                              </a-tooltip>
                            </div>
                          </template>
                        </a-image>
                      </div>
                    </template>
                  </a-space>
                </a-image-preview-group>
              </a-checkbox-group>
            </div>
          </div>
          <div class="table-footer mt-3 text-right" v-if="pagination.total > 0">
            <pagination-manage
              v-show="pagination.total > 0"
              :total="pagination.total"
              :current="pagination.current"
              :page-size="pagination.pageSize"
              :page-size-options="pagination.pageSizeOptions"
              @pageCBK="onPageChange"
              @pageSizeCBK="onPageSizeChange"
            />
          </div>
        </a-layout-content>
      </a-spin>
    </div>

    <SetColumn ref="setColumnRef" :columns="columns" @update:columns="updateColumns"/>
  </div>
</template>

<script setup>
  import { ref, reactive, h, compile, nextTick, computed, onMounted, onUnmounted } from 'vue';
  import { Message, Modal } from '@arco-design/web-vue';

  import useLoading from '@/hooks/loading';
  import { workAreaHeight, apiDownloadFile } from '@/utils/index';
  import tool from '@/utils/tool';
  import { apiList, apiDel, apiDisable } from '@/api/file';
  import PaginationManage from '@/components/pagination/index.vue';
  import VueTableColumn from '@/components/table/table-column.vue';
  import SetColumn from '@/components/table/set-column.vue';
  import TreeSlider from '@/components/tree-slider/index.vue';
  import FileUpload from '@/components/file-upload/index.vue';
  import FileView from '@/components/file-upload/view.vue';

  const props = defineProps({
    folder: {
      type: String,
      default: '',
    },
    fileType: {
      type: String,
      default: '',
    },
    ids: {
      type: Array,
      default() {
        return [];
      },
    },
  });
  const emit = defineEmits(['fileCancelCallback', 'fileOkCallback']);

  const { loading, setLoading } = useLoading(true);
  const basePagination = {
    current: 1,
    pageSize: 20,
    showTotal: true,
    showJumper: true,
    showPageSize: true,
    pageSizeOptions: [10, 20, 30, 50, 100, 150, 200, 300, 500],
  };
  const baseQuery = () => {
    return {
      page: 1,
      limit: 18,
      folder: props.folder,
      file_type: props.fileType,
      time_type: 'created_at',
      range_date: [],
    };
  };
  const baseColumns = [
    {
      title: 'ID', dataIndex: 'id', width: 80,
      align: 'center', fixed: 'left',
      sortable: {sortDirections: ['ascend', 'descend']},
    },
    {
      title: '文件', dataIndex: 'file_url', width: 80,
      align: 'center',
      slotName: 'file_url',
    },
    {
      title: '文件类型', dataIndex: 'file_type',  width: 120,
      align: 'center',
    },
    {
      title: '文件大小', dataIndex: 'file_size',  width: 100,
      align: 'center',
    },
    {
      title: '文件夹', dataIndex: 'folder',  width: 100,
      align: 'center',
    },
    {
      title: '存储位置', dataIndex: 'storage',  width: 100,
      align: 'center',
    },
    {
      title: '创建时间', dataIndex: 'created_at', width: 180,
      align: 'center',
      sortable: {sortDirections: ['ascend', 'descend']},
    },
    {
      title: '操作', dataIndex: 'operations', width: 80,
      align: 'center', fixed: 'right',
      slotName: 'operations',
    },
  ];
  const columns = ref(tool.local.get('columns-file') || baseColumns);
  const renderData = ref([]);
  const query = ref(baseQuery());
  const pagination = reactive({
    ...basePagination,
  });
  const rowSelection = reactive({
    type: 'checkbox',
    selectedRowKeys: [],
    defaultSelectedRowKeys: [],
    showCheckedAll: true,
  });
  const tableScroll = ref({
    x: '100%',
    y: '100%',
  });
  const selectedIds = computed({
    get() {
      return props.ids;
    },
    set(val) {

    },
  });

  const searchRef = ref();
  const showSearch = ref(true);
  const tableContainerRef = ref();
  const tableRef = ref();
  const setColumnRef = ref();
  const searchHeight = ref(0);

  const isReset = ref(true); // 是否重置
  let selectionKeys = []; // 选中项ID
  let selectionDatas = []; // 选中项
  const checkIds = ref([]); // 选择项ID集合
  const checkAll = ref(false); // 是否全选
  const checkedAllInd = ref(false); // 是否为半选状态
  const checkedIds = ref([]);
  const spinLoading = ref(false);
  const spinTip = ref();
  const folders = ref([]);
  const fileTypes = ref([]);
  const defaultFileTypeKey = ref(['all']);

  const tableMode = ref('list');
  const fileViewRef = ref();
  const fileExt = ref();

  const settingFixedPage = () => {
    const workHeight = workAreaHeight();
    const tableHeight = workHeight - searchHeight.value;
    tableContainerRef.value.style.height = `${tableHeight}px`;
  };
  const resizeHandler = () => {
    settingFixedPage();
  };
  const toggleSearch = async () => {
    const dom = searchRef.value?.style;
    if (dom) {
      showSearch.value = !showSearch.value;
      await nextTick(() => {
        searchHeight.value = searchRef.value.offsetHeight;
        settingFixedPage();
      });
    }
  };
  const setTableColumns = () => {
    setColumnRef.value.init();
  };
  const updateColumns = (data) => {
    columns.value = data;
    tool.local.set('columns-file', columns.value);
  };

  // 分页
  const onPageChange = async (page) => {
    isReset.value = false;
    await fetchData({ ...query.value, page });
  };
  const onPageSizeChange = async (limit) => {
    isReset.value = false;
    await fetchData({ ...query.value, limit });
  };
  // 列表
  const fetchData = async (
    params = { ...query.value }
  ) => {
    setLoading(true);
    await reset();
    try {
      const { data } = await apiList(params);
      renderData.value = data.data;
      query.value.page = params.page;
      query.value.limit = params.limit;
      pagination.current = params.page;
      pagination.pageSize = params.limit;
      pagination.total = data.total;

      checkIds.value = data.ids;
      folders.value = data.folders;
      if (!fileTypes.value.length) {
        // data.file_types.unshift({ name: '所有', key: 'all' });
        data.file_types = [{ name: '所有', value: 'all' }, ...data.file_types];
        fileTypes.value = data.file_types;
      }
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  // 删除
  const del = (row) => {
    if (!row.length) {
      selectMsg();
    } else {
      let title = '删除';
      let message = `确定要删除选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
      let ids = row;
      if (row.length === 1 && row[0].id) {
        title = `${title}ID：${row[0].id}`;
        message = `确定要删除 <span style="color:red">${row[0].id} </span> 这条数据吗？`;
        ids = [row[0].id];
      }
      Modal.warning({
        title,
        content: () => h('div', { innerHTML: message }),
        closable: true,
        hideCancel: false,
        onOk: (async () => {
          setLoading(true);
          try {
            await apiDel({ids});
          } catch (err) {
            setLoading(false);
          } finally {
            await fetchData({...query.value});
            setLoading(false);
          }
        }),
      });
    }
  };
  // 启用/禁用
  const isActivate = async (row, isDisable) => {
    if (!row.length) {
      selectMsg();
    } else {
      let ids = row;
      if (row.length === 1 && row[0].id) {
        ids = [row[0].id];
      }

      if (isDisable === 0) {
        const title = '禁用文件';
        const message = `禁用文件会对已使用该文件的业务造成影响！<br>确定要禁用文件吗？`;
        Modal.warning({
          title,
          content: () => h('div', { innerHTML: message }),
          closable: true,
          hideCancel: false,
          onOk: (async () => {
            setLoading(true);
            try {
              await apiDisable({
                ids,
                status: isDisable,
              });
            } catch (err) {
              setLoading(false);
            } finally {
              await fetchData({...query.value});
              setLoading(false);
            }
          }),
        });
      } else {
        await apiDisable({
          ids,
          status: isDisable,
        });
        await fetchData({...query.value});
      }
    }
  };
  // 重置
  const reset = async () => {
    if (isReset.value) {
      rowSelection.selectedRowKeys = [];
      selectionKeys = [];
      checkedIds.value = [];
    } else {
      isReset.value = true;
    }
  };
  // 搜索
  const search = async () => {
    query.value.page = 1;
    await fetchData({...query.value});
  };
  // 刷新
  const refresh = async () => {
    query.value = baseQuery();
    await fetchData({...query.value});
  };

  const onTreeClick = async (selectedKeys) => {
    defaultFileTypeKey.value = selectedKeys;
    const value = selectedKeys[0];
    if (value === 'all') {
      query.value.file_type = '';
    } else {
      query.value.file_type = value;
    }
    await fetchData({...query.value});
  };

  const switchTableMode = () => {
    tableMode.value = tableMode.value === 'list' ? 'window' : 'list';
  }

  // 已选择的数据行发生改变时触发 -- table 表头
  const selectionChange = (rowKeys) => {
    rowSelection.selectedRowKeys = rowKeys;
    selectionKeys = rowKeys;
  };
  const selectMsg = (message) => {
    Message.info(message || '请选择需要操作的数据');
  };
  // 批量删除
  const batchDel = () => {
    del(selectionKeys);
  };
  // 全选操作 -- 自定义按钮
  const customSelectAll = (value) => {
    checkedAllInd.value = false;
    checkAll.value = value;
    if (value) {
      checkedIds.value = checkIds.value;
    } else {
      checkedIds.value = [];
    }
  };
  // 选择文件
  const selectGroup = (values) => {
    // console.log(values)
    rowSelection.selectedRowKeys = values;
    selectionKeys = values;
    const checkedLength = values.length;
    checkAll.value = checkedLength === checkIds.value.length;
    checkedAllInd.value = checkedLength > 0 && checkedLength < checkIds.value.length;
  };
  // 筛选切换
  const filterSelect = async (folder = '', type = '') => {
    query.value.folder = folder;
    query.value.file_type = type;
    await fetchData({...query.value});
  };
  const viewFile = (file) => {
    fileExt.value = file.file_type;
    const src = file.full_file_url;
    if (src) {
      fileViewRef.value.viewFile(src);
    }
  };
  // const download = (src: string) => {
  //   if (src) {
  //     fileViewRef.value.download(src);
  //   }
  // };
  const download = (src) => {
    if (src) {
      apiDownloadFile(src);
    }
  };

  // 上传回调
  const uploadCallback = () => {
    refresh();
  };

  // 回调
  const fileCancel = () => {
    emit('fileCancelCallback');
  };
  const fileOk = () => {
    if (!selectionKeys.length) {
      selectMsg('请选择文件');
    } else {
      renderData.value.forEach((item, index) => {
        if (selectionKeys.includes(item.id)) {
          selectionDatas.push(item);
        }
      });
      emit('fileOkCallback', selectionDatas);
    }
  };

  // 初始化
  const initData = (ids) => {
    rowSelection.defaultSelectedRowKeys = ids;

    fetchData();
  };

  onMounted(async () => {
    initData();
    window.addEventListener('resize', resizeHandler, false);
    searchHeight.value = searchRef.value.offsetHeight;
    settingFixedPage();
  });
  onUnmounted(() => {
    window.removeEventListener('resize', resizeHandler, false);
  });
</script>

<style lang="less">
  .arco-upload-list {
    display: none;
  };
</style>
<style scoped lang="less">
/* :deep(.arco-image) {
border-radius: var(--border-radius-medium);
}
:deep(.arco-image-with-footer-inner .arco-image-footer) {
border-bottom-right-radius: var(--border-radius-medium);
border-bottom-left-radius: var(--border-radius-medium);
} */
:deep(.arco-image-img) {
  object-fit: contain;
  background-color: var(--color-fill-4);
}
:deep(.arco-image-with-footer-inner .arco-image-footer) {
  padding: 9px;
}
:deep(.arco-image-footer-caption-title) {
  font-size: 14px;
}
:deep(.arco-image-footer-extra) {
  position: relative;
}
:deep(.arco-avatar-square) {
  top: -6px;
}
.window-list {
  display: flex;
  width: 100%;
  flex-wrap: wrap;
  flex-direction: row;
  align-content: center;
}
.image-content {
  position: relative
}
.image-content .checkbox {
  position: absolute;
  z-index: 10;
  /*right: -16px;*/
  left: -4px;
  color: #fff;
}
:deep(.arco-tag-checkable) {
  color: #fff;
  background: rgba(0,0,0,.5);
}
/* :deep(.arco-tag-checkable:hover) {
  color: #555;
} */
.actions {
  display: flex;
  align-items: center;
  position:absolute;
  right: 9px; bottom: -24px;
}
.action {
  padding: 5px 4px;
  font-size: 14px;
  margin-left: 6px;
  border-radius: 2px;
  line-height: 1;
  cursor: pointer;
}
.action:first-child {
  margin-left: 0;
}

.action:hover {
  background: rgba(0,0,0,.5);
}
</style>